﻿using Dapper;
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Reflection;

namespace SPDB.BTAP.Infrastructure.Data.DapperCore
{
    public class ExecuteSql<TModel> where TModel : class
    {
        #region Insert非Null属性的对象实例+Insert(TModel model)
        /// <summary>
        /// Insert非Null属性的对象实例
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public virtual int Insert(TModel model)
        {
            string sql = DataMapping<TModel>.GetInsertSql(model);
            object res = DataBaseAccess.ExecuteScalar(sql, model);
            if (res != null)
            {
                return Convert.ToInt32(res);
            }
            return 0;
        }
        #endregion

        #region Select * 查询+Query()
        /// <summary>
        /// Select * 查询
        /// </summary>    
        /// <returns></returns>
        public virtual List<TModel> Query()
        {
            string sql = DataMapping<TModel>.GetQuerySql();
            return DataBaseAccess.Query<TModel>(sql);
        }
        #endregion

        #region 带查询条件的Select查询+Query(Func<TModel, bool> selector)
        ///// <summary>
        ///// 带查询条件的Select查询
        ///// </summary>
        ///// <param name="selector"></param>
        ///// <returns></returns>
        //public virtual List<TModel> Query(Func<TModel, bool> selector)
        //{
        //    string sql = DataMapping<TModel>.GetQuerySql();
        //    return DataBaseAccess.Query<TModel>(sql, selector);
        //}
        #endregion

        #region 带查询条件的Select查询+Query(Expression<Func<TModel, bool>> selector)
        /// <summary>
        /// 带查询条件的（Sql脚本）Select查询
        /// </summary>
        /// <param name="selector"></param>
        /// <returns></returns>
        public virtual List<TModel> Query(Expression<Func<TModel, bool>> selector)
        {
            string sql = DataMapping<TModel>.GetQuerySql();
            sql += " where " + ExtendDapper.Where<TModel>(selector);
            return DataBaseAccess.Query<TModel>(sql);
        }
        #endregion

        #region  得到一个对象的实例+FirstOrDefault(Func<TModel, bool> selector = null)
        /// <summary>
        /// 得到一个对象的实例
        /// </summary>
        /// <param name="selector"></param>
        /// <returns></returns>
        public virtual TModel FirstOrDefault(Func<TModel, bool> selector = null)
        {
            string sql = DataMapping<TModel>.GetQuerySql();
            return DataBaseAccess.FirstOrDefault<TModel>(sql, selector);
        }
        #endregion

        #region 批量删除+Delete(string[] IdList)
        /// <summary>
        /// 批量删除
        /// </summary>
        /// <param name="IdList"></param>
        /// <returns></returns>
        public virtual int Delete(string[] IdList)
        {
            return DataBaseAccess.Execute(DataMapping<TModel>.GetDeleteSql(), new { IdList = IdList });
        }
        #endregion

        #region Delete(string primaryKey)
        /// <summary>
        /// 删除
        /// </summary>
        /// <param name="IdList"></param>
        /// <returns></returns>
        public virtual int Delete(string primaryKey)
        {
            return DataBaseAccess.Execute(DataMapping<TModel>.GetDeleteSqlSingle(), new { PrimaryKey = primaryKey });
        }
        #endregion

        #region Delete(int primaryKey)
        /// <summary>
        /// 删除
        /// </summary>
        /// <param name="IdList"></param>
        /// <returns></returns>
        public virtual int Delete(int primaryKey)
        {
            return DataBaseAccess.Execute(DataMapping<TModel>.GetDeleteSqlSingle(), new { PrimaryKey = primaryKey });
        }
        #endregion

        #region Delete(TModel model)
        /// <summary>
        /// 删除
        /// </summary>
        /// <param name="IdList"></param>
        /// <returns></returns>
        public virtual int Delete(TModel model)
        {
            return DataBaseAccess.Execute(DataMapping<TModel>.GetDeleteSqlSingle(model), model);
        }
        #endregion

        #region Update 一个非Null属性的对象+Update(TModel model)
        /// <summary>
        /// Update 一个非Null属性的对象
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public virtual int Update(TModel model)
        {
            return DataBaseAccess.Execute(DataMapping<TModel>.GetUpdateSql(model), model);
        }
        #endregion

        #region Save 一个非Null属性的对象+Save(TModel model)
        /// <summary>
        /// Save 一个非Null属性的对象
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public virtual int Save(TModel model)
        {
            if (model == null)
            {
                return -10000;
            }

            bool isExists = IsExists(model);

            //得到类型
            Type modelType = typeof(TModel);

            //取得属性集合
            PropertyInfo[] pi = modelType.GetProperties();

            foreach (PropertyInfo info in pi)
            {
                if (info.Name == "CreateDate" && !isExists)
                {
                    info.SetValue(model, DateTime.Now);
                }
                else if (info.Name == "UpdateDate")
                {
                    info.SetValue(model, DateTime.Now);
                }
            }

            if (isExists)
            {
                return Update(model);
            }
            else
            {
                return Insert(model);
            }
        }
        #endregion

        #region Exists 一个非Null属性的对象+Update(TModel model)
        /// <summary>
        /// Update 一个非Null属性的对象
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public virtual bool IsExists(TModel model)
        {
            string sql = DataMapping<TModel>.GetQuerySqlWithKeys();
            object res = DataBaseAccess.ExecuteScalar(sql, model);
            if (res == null)
            {
                return false;
            }
            else
            {
                return true;
            }
        }
        #endregion

        #region 获取多个数据集+MultyQuery(string sql, object param = null)
        /// <summary>
        /// 获取多个数据集
        /// </summary>
        /// <param name="sql"></param>
        /// <param name="param"></param>
        /// <returns></returns>
        public virtual SqlMapper.GridReader MultyQuery(string sql, object param = null)
        {
            return DataBaseAccess.MultyQuery(sql, param);
        }
        #endregion


    }
}